package com.mamingchao.concurrent.map;

import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 没用key 引用指向的Entry都会被回收
 *
 * Created by mamingchao on 2020/12/22.
 */
public class WeakHashMapTest {

    private static WeakHashMap<Object,Object> testMap = new WeakHashMap<>();

    public static void main(String[] args) throws InterruptedException {
        MapKey key = new MapKey("coming home");
        for (int i = 0; i < 100; i++) {
            if (i == 10) {
                //map 第10个Entry 有 强引用指向（即key）
                testMap.put(key,"value" + i);
            } else {
                //除 第10个Entry，其他元素都没用引用指向
                testMap.put(new MapKey("key-" + i),"value" + i);
            }
        }


        System.out.println(testMap.size());

        //第一次gc的时候，除了第10个元素，其他全部被回收
        System.gc();

        TimeUnit.SECONDS.sleep(2);

        System.out.println(testMap.size());

        //设置第10个元素的key 引用指向null
        key = null;

        //第10个元素也被gc
        System.gc();

        TimeUnit.SECONDS.sleep(2);

        System.out.println(testMap.size());

        //WeakHashMap不能用基础类型做key，因为WeakHashMap 会自动给基础类型装箱，然后每个装箱类带有 常量池
        //比如int -》Integer，常量池 -127  到  128  正好 256个元素
        for (int i = -150; i < 150; i++) {
            testMap.put(i,"value" + i);
        }

        System.gc();

        TimeUnit.SECONDS.sleep(2);

        System.out.println(testMap.size());

    }



    static class MapKey{
        String keyName;
        MapKey(String keyName) {
            this.keyName = keyName;
        }

        @Override
        public String toString() {
            return "MapKey{" +
                    "keyName='" + keyName + '\'' +
                    '}';
        }
    }

}
